//
//  gridview.m
//  OpenglPing
//
//  Created by 100TV protocal on 12-11-28.
//
//

#import "gridview.h"
#import "xibhelp.h"
#import <QuartzCore/QuartzCore.h>
#import <objc/runtime.h>
//btn
@implementation UIButton(par)
@dynamic nParameter;
- (id)nParameter {
    return objc_getAssociatedObject(self, @"nParameterKey");
}
- (void)setNParameter:(NSNumber *)nParameter {
    objc_setAssociatedObject(self, @"nParameterKey", nParameter, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end

//cell
@implementation gridviewcell
@synthesize index;
-(NSString *) reuseIdentifier {
	NSString* ret=nil;
	if(m_reuseIdentifier!=nil){
		ret=[[m_reuseIdentifier copy] autorelease];
	}else{
		ret=[[self class] description];
	}
	return ret;
}
-(id) initWithFrame:(CGRect)frame reuseIdentifier:(NSString*) identifier{
	if((self=[super initWithFrame:frame])){
		m_reuseIdentifier=[identifier copy];
	}
	return self;
}
@end

//bookcell
@implementation gridviewbookcell
@synthesize index;
-(NSString *) reuseIdentifier {
	NSString* ret=nil;
	if(m_reuseIdentifier!=nil){
		ret=[[m_reuseIdentifier copy] autorelease];
	}else{
		ret=[[self class] description];
	}
	return ret;
}
-(id) initWithFrame:(CGRect)frame reuseIdentifier:(NSString*) identifier {
	if ((self=[super initWithFrame:frame])) {
		m_reuseIdentifier=[identifier copy];
	}
	return self;
}
@end

@implementation bookcell
-(void) dealloc{
    [super dealloc];
}
-(void) layoutSubviews {
    [super layoutSubviews];
}
-(NSString *) reuseIdentifier {
    return @"bookcell";
}
@end


//gridview
#define FN_TAG_GRIDVIEW 170
#define TAG_HEIGTHVIEW  9527
#define TAG_LOADINGVIEW 9528
#define TAG_EDIT 9529
#define TAG_DELETE 9530

#define RGBACOLOR(_r, _g, _b, _a) [UIColor colorWithRed:(_r)/255.0 green:(_g)/255.0 blue:(_b)/255.0 alpha:(_a)]
#define LOADING_TAG_LABEL 1001
#define LOADING_TAG_IMAGE 1002
#define LOADING_TAG_LOADING 1003
#define LOADING_HEIGHT -100
#define LOADING_WAIT_HEIGHT 50
#define LOADING_IMAGE @"blueArrow.png"
#define LOADING_LABEL_A @"下拉可以刷新..."
#define LOADING_LABEL_B @"松开即可刷新..."
#define LOADING_LABEL_C @"正在加载..."
#define BOOKSTORE_WIDTH 768
#define BOOKSTORE_HEIGTH 160

@implementation gridview
@synthesize dataSource;
@synthesize delegate_grid;
@synthesize headerView;
@synthesize footerView;
@synthesize headerHeight;
@synthesize isBookStore;
@synthesize left_width;
@synthesize delete_button_offsetX;

-(void) internalInit{
#pragma mark 俩字典！数据源！
	visibleCellDictionary=[[NSMutableDictionary  alloc] init];
	dequeArray=[[NSMutableDictionary alloc] init];
	self.clipsToBounds=YES;
    cellFrameArray=[[NSMutableArray alloc] init];
    revertFrameH= self.bounds.size.height;
    
    _selectedIndex = NSNotFound;
    
    //book
    visibleCellDictionaryBook=[[NSMutableDictionary alloc] init];
    dequeArrayBook=[[NSMutableDictionary alloc] init];
    _gridFlags.isBgBookStore = 0;
    self.tag = FN_TAG_GRIDVIEW;
    left_width = -1;
}
-(id) initWithFrame:(CGRect)frame{
	if((self=[super initWithFrame:frame])){
        [self internalInit];
    }
	return self;
}
-(id) initWithCoder:(NSCoder *)aDecoder{
	if((self=[super initWithCoder:aDecoder])){
		[self internalInit];
	}
	return self;
}
-(void)revert{
    CGRect frame=CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, revertFrameH);
    self.frame=frame;
}

//怎样才能在这个方法执行之前找一个只会执行一次的方法,用来存放
-(void) layoutSubviews{
	NSAutoreleasePool* pool=[[NSAutoreleasePool alloc] init];
	////!! //NSLog(@"%s",__FUNCTION__);
    BOOL one=YES;
    if (one) {
        if (getRidOfAnimation) {
            if ([cellFrameArray count]!=0) {
                CGRect rect=CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, 1500);
                self.frame=rect;
            }
        }
    }
    
    if (dataSource == nil) {
        [pool release];
        return;
    }
    
	CGSize sz = [dataSource sizeOfGridViewItem:self];//!
	int numOfItems=[dataSource numOfGridViewItem:self];//!
	int numOfCol=(int)floor( self.bounds.size.width/sz.width);//
    
	if(numOfCol<1){numOfCol=1;}//!
	int numOfRow= (int)ceil(numOfItems/(float)numOfCol);//!
    
	float contentHeight=numOfRow*(sz.height);//!
	float contentWidth=numOfCol*sz.width;//算出contentSize
    
	if(contentWidth<self.bounds.size.width){
		contentWidth=self.bounds.size.width;
	}
	float hspacer=(contentWidth-(numOfCol*sz.width))/2.0;
    float footerHeight = 0;
    if (left_width>-1) {
        hspacer=left_width;
    }
    
	CGRect visibleRect;//可见rect
	visibleRect.origin=self.contentOffset;//（100，0）
	visibleRect.size=self.bounds.size;//（320，480）   nice rect
    //减缓内存复用
    visibleRect.origin.y = visibleRect.origin.y-sz.height;
    visibleRect.size.height = visibleRect.size.height+sz.height;
    
	@synchronized(visibleCellDictionary)
    {
        //block 可见cell数组
		for(int i=0;i<numOfItems;++i){//遍历每个cell
			NSAutoreleasePool* pool2=[[NSAutoreleasePool alloc] init];
			int colindex=i%numOfCol;
            //希望计算的x＝
            float x=hspacer+sz.width*colindex;
            
			//float x=(colindex)*sz.width+hspacer*(colindex+1);
			int rowindex=floor(i/(float)numOfCol);
			float y=rowindex*sz.height+headerHeight;
            
			id indexKey=[NSNumber numberWithInt:i];
			gridviewcell* cell=[visibleCellDictionary objectForKey:indexKey];//这个字典里面顺序排列每个cell，第一次去不出来
            
            CGRect cellFrame=CGRectMake(x, y, sz.width, sz.height);
            NSValue *value=[NSValue valueWithCGRect:cellFrame];
            
			if(CGRectIntersectsRect(visibleRect, cellFrame)){//当前cell的frame与可见rect做相交判断，如果相交成功调用这个
				if(nil==cell){
					cell=[dataSource gridView:self cellForIndex:i];
                    cell.backgroundColor = [UIColor clearColor];
                    //编辑按钮
                    if (_gridFlags.isEditing) {
                        if (_selectedIndex == i) {
                            _systemEdit_Delete = [UIButton buttonWithType:UIButtonTypeCustom];
                            [_systemEdit_Delete setFrame:CGRectMake((sz.width-52)/2 + delete_button_offsetX, (sz.height-32)/2, 52, 32)];
                            //                            _systemEdit_Delete.center = CGPointMake(cellFrame.size.width/2, cellFrame.size.height/2);
                            _systemEdit_Delete.tag = TAG_DELETE;
                            [_systemEdit_Delete setTitle:@"删除" forState:UIControlStateNormal];
                            _systemEdit_Delete.titleLabel.font = [UIFont systemFontOfSize:14];
                            _systemEdit_Delete.titleLabel.shadowOffset = CGSizeMake(0, -1);
                            [_systemEdit_Delete setBackgroundImage:[UIImage imageNamed:@"edit_button_delete.png"] forState:UIControlStateNormal];
                            [_systemEdit_Delete setNParameter:[NSNumber numberWithInt:i]];
                            [_systemEdit_Delete addTarget:self action:@selector(doDelete:) forControlEvents:UIControlEventTouchUpInside];
                            [cell addSubview:_systemEdit_Delete];
                        } else {
                            _systemEdit_Select = [UIButton buttonWithType:UIButtonTypeCustom];
                            [_systemEdit_Select setFrame:CGRectMake((sz.width-44)/2 + delete_button_offsetX, (sz.height-44)/2, 44, 44)];
                            _systemEdit_Select.tag = TAG_EDIT;
                            [_systemEdit_Select setBackgroundImage:[UIImage imageNamed:@"edit_button_reduce.png"] forState:UIControlStateNormal];
                            [_systemEdit_Select setNParameter:[NSNumber numberWithInt:i]];
                            [_systemEdit_Select addTarget:self action:@selector(doEdit:) forControlEvents:UIControlEventTouchUpInside];
                            [cell addSubview:_systemEdit_Select];
                        }
                    }
				}
                
				assert(cell!=nil);
				cell.index=i;
				cell.frame=cellFrame;
				[self addSubview:cell];
                if (cellFrameArray!=nil&&getRidOfAnimation&&[cellFrameArray count]>i) {
                    
                    
					NSValue *oldValue=[cellFrameArray objectAtIndex:i];
					
                    if (![oldValue isEqualToValue:value]) {
						cell.frame=[oldValue CGRectValue];
						//减淡
						for (UIView *view in [cell subviews]) {
                            //							if([view isKindOfClass:[UrlImageView class]]){
                            //								continue;
                            //							}
                            view.alpha=0;
						}
                        
                        [UIView beginAnimations:nil context:nil];
                        [UIView setAnimationDuration:1];
                        
                        cell.frame=cellFrame;
                        if (one) {
                            one=NO;
                            [UIView setAnimationDelegate:self];
                            [UIView setAnimationDidStopSelector:@selector(revert)];
                        }
                        [UIView commitAnimations];
                        //减淡动画
                        
                        [UIView beginAnimations:nil context:nil];
                        [UIView setAnimationDuration:3.0];
                        for (UIView *view in [cell subviews]) {
                            //类型为urlimageview的控件不做动画
                            //							if([view isKindOfClass:[UrlImageView class]]){
                            //								continue;
                            //							}
                            
                            view.alpha=1;
						}
                        
                        [UIView commitAnimations];
                        
                        [cellFrameArray replaceObjectAtIndex:i withObject:value];
                    }else{
                        [self revert];
                    }
					
                }
				[self sendSubviewToBack:cell];
                if (!_gridFlags.isEditing) {
                    [cell addTarget:self action:@selector(onTouchDown:) forControlEvents:UIControlEventTouchDown];
                    [cell addTarget:self action:@selector(onCellTouch:) forControlEvents:UIControlEventTouchUpInside];
                    [cell addTarget:self action:@selector(onTouchUp:) forControlEvents:UIControlEventTouchUpInside];
                    [cell addTarget:self action:@selector(onTouchOutSizeUp:) forControlEvents:UIControlEventTouchUpOutside];
                }
				
                //                DLog(@"cell:%p,indexKey:%d", cell, [indexKey intValue]);
				[visibleCellDictionary setObject:cell forKey:indexKey];
				assert(cell.superview==self);
				if(delegate_grid!=nil && [delegate_grid respondsToSelector:@selector(gridView:willDisplayCell:atIndex:)]){
					[delegate_grid gridView:self willDisplayCell:cell atIndex:i];
				}
			}else{
				if(cell!=nil){//判断到这个cell变为不可见了！！，如果这个cell存在！！取出identifier对应的队列
					id identifier=[cell reuseIdentifier];
					if(identifier!=nil){
						NSMutableArray* dequeCellArray=(NSMutableArray*)[dequeArray objectForKey:identifier];
						if(dequeCellArray==nil){
							dequeCellArray=[[[NSMutableArray alloc] init] autorelease];
							[dequeArray setObject:dequeCellArray forKey:identifier];
						}
						@synchronized(dequeCellArray){
                            [[cell viewWithTag:TAG_DELETE] removeFromSuperview];
                            [[cell viewWithTag:TAG_EDIT] removeFromSuperview];
							[dequeCellArray addObject:cell];
						}
					}
                    if ([dataSource respondsToSelector:@selector(cellWillDisAppear:)]) {
                        [dataSource cellWillDisAppear:cell];
                    }
					[cell removeFromSuperview];
				}
                
                if ([[[visibleCellDictionary keyEnumerator] allObjects] containsObject:indexKey])
                {
                    [visibleCellDictionary removeObjectForKey:indexKey];
                }
			}
            
            if (i==numOfItems-1) {
                getRidOfAnimation=NO;
            }
            if (i+1>[cellFrameArray count]) {
                [cellFrameArray addObject:value];
            }else {
                [cellFrameArray replaceObjectAtIndex:i withObject:value];
            }
            
			[pool2 release];
		}
        //show footer
		if ([dataSource respondsToSelector:@selector(heightOfGridViewFooter:)]){
			footerHeight=[dataSource heightOfGridViewFooter:self];
			if(footerHeight>0){
				CGRect footerFrame=CGRectMake(0	, contentHeight , self.bounds.size.width, footerHeight);
				//if(CGRectIntersectsRect(visibleRect, footerFrame)){
                [footerView removeFromSuperview];
                footerView=[dataSource footerOfGridView:self];
                if(nil!=footerView){
                    footerView.frame=footerFrame;
                    [self addSubview:footerView];
                }
				//}
			}else{
				[footerView removeFromSuperview];
			}
		}
	}
    //bookStore
    @synchronized(visibleCellDictionaryBook) {
        if (_gridFlags.isBgBookStore == 1) {
            NSInteger minNumberOfCells = ceilf(self.bounds.size.height/ sz.height);
            NSInteger maxNumberOfCells = MAX(numOfRow, minNumberOfCells) + 2;
            //do action
            for (int i = 0; i < maxNumberOfCells; i++) {
                NSAutoreleasePool* pool2=[[NSAutoreleasePool alloc] init];
                
                float x = 0;
                float y = i*sz.height+0;
                CGRect cellFrame = CGRectMake(x, y, contentWidth, sz.height);
                id indexKey=[NSNumber numberWithInt:i];
                gridviewbookcell* cell = [visibleCellDictionaryBook objectForKey:indexKey];
                if(CGRectIntersectsRect(visibleRect, cellFrame)){
                    //在可视区域
                    if(nil==cell){
                        static NSString * cellIdentity = @"bookcell";
                        bookcell * bookcellitem = (bookcell*)[self dequeueReusableBookCellWithIdentifier:cellIdentity];
                        if (bookcellitem == nil) {
                            bookcellitem = (bookcell*)[xibhelp loadObjectFromXIBName:@"bookcell" type:[bookcell class]];
                        }
                        cell = bookcellitem;
                    }
                    assert(cell!=nil);
                    cell.index=i;
                    cell.frame=cellFrame;
                    [self addSubview:cell];
                    //如果不send to back 会把滚动条盖住
                    [self sendSubviewToBack:cell];
                    
                    [visibleCellDictionaryBook setObject:cell forKey:indexKey];
                    assert(cell.superview==self);
                }else{
                    //不在可视区域
                    if(cell!=nil){
                        id identifier=[cell reuseIdentifier];
                        if(identifier!=nil){
                            NSMutableArray* dequeCellArray=(NSMutableArray*)[dequeArrayBook objectForKey:identifier];
                            if(dequeCellArray==nil){
                                dequeCellArray=[[[NSMutableArray alloc] init] autorelease];
                                [dequeArrayBook setObject:dequeCellArray forKey:identifier];
                            }
                            @synchronized(dequeCellArray){
                                [dequeCellArray addObject:cell];
                            }
                        }
                        [cell removeFromSuperview];
                    }
                    [visibleCellDictionaryBook removeObjectForKey:indexKey];
                }
                [pool2 release];
            }
        }
    }
    
    float tempheight = contentHeight+footerHeight+headerHeight;
    if (tempheight < self.bounds.size.height) {
        tempheight = self.bounds.size.height+1;
    }
    self.contentSize=CGSizeMake(contentWidth, tempheight);
    self.delegate = (id<UIScrollViewDelegate>)self;
	[pool release];
    [super layoutSubviews];
}

- (void) setHeaderView: (UIView *) newHeaderView
{
	if ( newHeaderView == headerView )
		return;
    
	[headerView removeFromSuperview];//.莫非
	[headerView release];//两次释放到底为了谁
    
	headerView = [newHeaderView retain];
	if ( headerView == nil )
	{
		headerHeight = 0.0;
	}
	else
	{
        headerView.frame=CGRectMake(0, 0, headerView.frame.size.width, headerView.frame.size.height);
		[self addSubview: headerView];
        [headerView release];
		headerHeight = headerView.frame.size.height;
	}
	//[self setNeedsLayout];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    //finger up
    if (loadData) {
    }
}

-(void) dealloc{
    self.contentOffset=CGPointZero;
	[visibleCellDictionary release];visibleCellDictionary=nil;
	[dequeArray release];dequeArray=nil;
    [cellFrameArray release];cellFrameArray=nil;
    //book
    [visibleCellDictionaryBook release];visibleCellDictionaryBook=nil;
    [dequeArrayBook release];dequeArrayBook=nil;
	[super dealloc];
}

- (gridviewcell *) dequeueReusableCellWithIdentifier:(NSString *)identifier{
	NSAutoreleasePool* pool=[[NSAutoreleasePool alloc] init];
	gridviewcell* ret=nil;
	NSMutableArray* dequeCellArray=(NSMutableArray*)[dequeArray objectForKey:identifier];
	if(dequeCellArray!=nil ){
		@synchronized(dequeCellArray){
			if([dequeCellArray count]>0){
				ret=(gridviewcell*)[[dequeCellArray lastObject] retain];
                [ret viewWithTag:TAG_EDIT].hidden = YES;
                [ret viewWithTag:TAG_DELETE].hidden = YES;
				[dequeCellArray removeObject:ret];
			}
		}
	}
	[pool release];
	return [ret autorelease];
}

- (gridviewbookcell*)dequeueReusableBookCellWithIdentifier:(NSString *)identifiler
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    gridviewbookcell* ret=nil;
    NSMutableArray* dequeCellArray=(NSMutableArray*)[dequeArrayBook objectForKey:identifiler];
    if (dequeCellArray!=nil) {
        @synchronized(dequeCellArray){
            ret=[(gridviewbookcell*)[dequeCellArray lastObject] retain];
            [dequeCellArray removeObject:ret];
        }
    }
    [pool release];
    return [ret autorelease];
}

//event
-(void)onTouchDown:(id)sender{
	gridviewcell* cell=(gridviewcell*)sender;
	if(delegate_grid!=nil && [delegate_grid respondsToSelector:@selector(gridView:willSelectCell:atIndex:)] ){
		[delegate_grid gridView:self willSelectCell:cell atIndex:cell.index];
	}
}
-(void) onCellTouch:(id) sender{
	gridviewcell* cell=(gridviewcell*)sender;
	if(delegate_grid!=nil && [delegate_grid respondsToSelector:@selector(gridView:didSelectCell:atIndex:)] ){
		[delegate_grid gridView:self didSelectCell:cell atIndex:cell.index];
	}
}
-(void)onTouchUp:(id)sender{
    gridviewcell* cell = (gridviewcell*)sender;
    if (delegate_grid != nil && [delegate_grid respondsToSelector:@selector(gridView:didSelectCellUp:atIndex:)]) {
        [delegate_grid gridView:self didSelectCellUp:cell atIndex:cell.index];
    }
}
-(void)onTouchOutSizeUp:(id)sender{
    gridviewcell* cell = (gridviewcell*)sender;
    if (delegate_grid != nil && [delegate_grid respondsToSelector:@selector(gridView:didSelectCellOutSizeUp:atIndex:)]) {
        [delegate_grid gridView:self didSelectCellOutSizeUp:cell atIndex:cell.index];
    }
}

-(void) reloadCellAtIndex:(int)index{
	NSNumber* key=[NSNumber numberWithInt:index];
	gridviewcell* cell=[visibleCellDictionary objectForKey:key];
	if(nil!=cell){
		[cell removeFromSuperview];
		[visibleCellDictionary removeObjectForKey:key];
	}
	[self setNeedsLayout];
}

-(gridviewcell *) getCellAtIndex:(int)index
{
    NSNumber* key=[NSNumber numberWithInt:index];
	gridviewcell* cell=[visibleCellDictionary objectForKey:key];
    return cell;
}

-(void) reloadFooter{
	[footerView removeFromSuperview];
	footerView=nil;
	[self setNeedsLayout];
}

-(void) reloadData{
	for(id key in [visibleCellDictionary allKeys]){
		UIView* v=[visibleCellDictionary objectForKey:key];
		[v removeFromSuperview];
	}
	
	[visibleCellDictionary removeAllObjects];
	[self setNeedsLayout];
}

- (void) setIsBookStore:(BOOL)isBook
{
    if (isBook) {
        _gridFlags.isBgBookStore = 1;
    } else {
        _gridFlags.isBgBookStore = 0;
    }
}

- (void)doDelete:(id)sender
{
    UIButton* tag = (UIButton*)sender;
    if (_selectedIndex != [[tag nParameter] intValue]) {
        return;
    }
    if (delegate_grid != nil && [delegate_grid respondsToSelector:@selector(gridView:commitEditingStyle:atIndex:)]) {
        [delegate_grid gridView:self commitEditingStyle:UIGridViewCellEditingStyleDelete atIndex:_selectedIndex];
    }
    _selectedIndex = NSNotFound;
    //刷新页面
    [self reloadData];
}

#pragma mark - (uialertdelegate)
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {
        if (delegate_grid != nil && [delegate_grid respondsToSelector:@selector(gridView:commitEditingStyle:atIndex:)]) {
            [delegate_grid gridView:self commitEditingStyle:UIGridViewCellEditingStyleDelete atIndex:_selectedIndex];
        }
        _selectedIndex = NSNotFound;
        //刷新页面
        [self reloadData];
    }
}

- (void)doEdit:(id)sender
{
    UIButton* tag = (UIButton*)sender;
    [UIView animateWithDuration:0.3 animations:^{
        [tag layer].transform = CATransform3DMakeRotation(M_PI * 1, 0.0f, 0.0f, 1.0f);
    } completion:^(BOOL finished) {
        [self _deselectItemAtIndex:[[tag nParameter] intValue] animated:_gridFlags.isAnimation];
    }];
}

- (BOOL) isEditing
{
	return ( _gridFlags.isEditing == 1 );
}

- (void) setEditing: (BOOL) value
{
	[self setEditing:value animated:NO];
}

- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
	_gridFlags.isEditing = (editing ? 1 : 0);
    _gridFlags.isAnimation = (animated ? 1 : 0);
    _selectedIndex = NSNotFound;
    [self reloadData];
}

- (void) _deselectItemAtIndex:(NSUInteger)index animated:(BOOL)animated
{
    NSInteger st = _selectedIndex;
    _selectedIndex = index;
    if (st != NSNotFound) {
        [self reloadCellAtIndex:st];
    }
    [self reloadCellAtIndex:index];
}

@end
